<?php

namespace App\Service\Common;

use App\Common\ResponseCode;
use App\Common\Tools;
use App\Exceptions\BusinessException;
use App\Extensions\Common\OssService;
use App\Jobs\MerchansCastingJob;
use App\Params\Common\SpecialApplyAddParam;
use App\Params\Common\SpecialApplyEditParam;
use App\Repository\MerchantsCastingRepo;
use App\Repository\MerchantsInfoRepo;
use App\Repository\SpecialAlbumRepo;
use App\Repository\SpecialApplyRepo;
use App\Service\BaseService;
use App\Traits\MoneyCalculator;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 *  藏品铸造申请列表
 */
class SpecialApplyService extends BaseService
{
    use MoneyCalculator;

    public function getList()
    {

    }

    /**
     *  藏品申请修改
     * @throws BusinessException
     */
    public function edit(SpecialApplyEditParam $params)
    {
        // 接入商户信息
        $merchants_info = MerchantsInfoRepo::getInstance()->getInfoByAccessMid($params->getMid());
        if (!$merchants_info) {
            throw new BusinessException(ResponseCode::MERCHANTS_NOT_FUND);
        }

        $album = SpecialAlbumRepo::getInstance()->getAlbumById($params->getAlbumId());
        if (empty($album) || $album->merchants_id != $merchants_info['merchants_id']) {
            throw new BusinessException(ResponseCode::SPECIAL_ALBUM_NOT_FOUND);
        }

        // 创作者的藏品详情
        $applyInfo = SpecialApplyRepo::getInstance()->getByCode($params->getCode());

        if (empty($applyInfo) || $applyInfo->merchants_id != $merchants_info['merchants_id']) {
            throw new BusinessException(ResponseCode::SPECIAL_NOT_FUND);
        }

        // 未审核或者审核驳回状态才可以更新
        if (!in_array($applyInfo['apply_status'], [1, 3])) {
            throw new BusinessException(ResponseCode::SPECIAL_CANT_NOTIFY);
        }
        $edit_data = [
            'story' => $params->getStory(),// 作品故事
            'merchants_id' => $merchants_info['merchants_id'],// 商户id
            'base_price' => $this->format($params->getPrice()),// 价格
            'sell_time' => $params->getSellTime(),// 售卖时间
            'special_album_id' => $album['id'],
            'is_resale' => $album['is_resale'],
            'is_donation' => $album['is_donation'],
            'label' => json_encode($params->getLabel()),
            "user_num" => $params->getUserNum() ?: $applyInfo['user_num'],
            "one_num" => $params->getOneNum(),
            "update_time" => Carbon::now(),
        ];
        // 更新藏品信息
        $res = SpecialApplyRepo::getInstance()->save($edit_data, $applyInfo->id);
        if (!$res) {
            Log::info('更新藏品信息失败:' . $params->getCode());
            throw new BusinessException(ResponseCode::SPECIAL_UPDATE_FAIL);
        }

        return [
            'code' => $params->getCode(),
        ];
    }

    /**
     *  藏品铸造申请新增
     * @throws BusinessException|\OSS\Core\OssException
     */
    public function add(SpecialApplyAddParam $params): array
    {
        // 接入商户信息
        $merchants_info = MerchantsInfoRepo::getInstance()->getInfoByAccessMid($params->getMid());
        if (empty($merchants_info)) {
            throw new BusinessException(ResponseCode::MERCHANTS_NOT_FUND);
        }

        // 新增时判断剩余铸造数不足
        if ($merchants_info['remaining'] < $params->getAllCount()) {
            throw new BusinessException(ResponseCode::MERCHANTS_REMAIN_CAST_NUM_NOT_ENOUGH);
        }

        // 查询专辑
        $album = SpecialAlbumRepo::getInstance()->getAlbumById($params->getAlbumId());
        if (empty($album) || $album->merchants_id != $merchants_info['merchants_id']) {
            throw new BusinessException(ResponseCode::SPECIAL_ALBUM_NOT_FOUND);
        }
        // 转存oss
        $thumb = OssService::getInstance()->saveFile($params->getThumb());
        if ($params->getType() == 10) {
            if ($this->compare($params->getPrice(), "0.50") < 0) {
                throw new BusinessException(ResponseCode::SPECIAL_PRICE_ILLEGAL);
            }
        }

        $insert_data = [
            'code' => Tools::buildRandomBn(),
            'title' => $params->getTitle(),// 专题名称
            'thumb' => $thumb,// 专题展示图
            'story' => $params->getStory(),// 作品故事
            'resources_type' => $params->getResourceType(),// 藏品图片类型
            'merchants_id' => $merchants_info['merchants_id'],// 商户id
            'base_price' => $this->format($params->getPrice()),// 价格
            'special_type_id' => 1,// 专题分类ID
            'all_count' => $params->getAllCount(),// 数量
            'status' => 0,// 上下架,0下架
            'is_sell_out' => 0,// 是否售罄 1是0否
            'cast_price' => 0,// 铸造服务费
            'sort' => 0,// 排序号
            'apply_status' => 1,// 审核状态 1审核中
            'reason' => '',// 拒绝原因
            'cast_status' => 1,// 铸造状态 1未铸造
            'sell_status' => 1,
            'sell_time' => $params->getSellTime(),// 售卖时间
            'special_album_id' => $album['id'],
            'is_resale' => $album['is_resale'],
            'is_donation' => $album['is_donation'],
            'type' => $params->getType(),// 类型
            'label' => json_encode($params->getLabel()),
            "user_num" => $params->getUserNum() ?: $params->getAllCount(),
            "one_num" => $params->getOneNum(),
            "serial_number" => Tools::buildRandomBn(),
        ];
        DB::beginTransaction();
        try {
            // 1.新增藏品
            $insert_data['create_time'] = date("Y-m-d H:i:s");
            $special_id = SpecialApplyRepo::getInstance()->save($insert_data);
            if (!$special_id) {
                throw new \Exception("新增藏品失败");
            }
            // 2.修改创作者剩余可铸造量
            $cast_update = MerchantsCastingRepo::getInstance()->updateRemaining($merchants_info['merchants_id'], $params->getAllCount());
            if (!$cast_update) {
                throw new \Exception("修改创作者剩余可铸造量失败");
            }
            DB::commit();
        } catch (\Exception $e) {
            Log::info("新增藏品异常:{$merchants_info['merchants_id']}," . $e->getMessage());
            DB::rollBack();
            throw new BusinessException(ResponseCode::SPECIAL_CREATE_ERROR);
        }
        // 写入创作者铸造消耗日志
        $serial_number = MerchantsCastingService::getInstance()->checkSerialNumber(Tools::build_hash_no());
        $log = [
            'mer_id'=>$merchants_info['merchants_id'],
            'access_id'=>$params->getMid(),
            'num'=>$params->getAllCount(),
            'serial_number'=>$serial_number,
            'before_change'=>$merchants_info['remaining'],
            'after_change'=>$merchants_info['remaining'] - $params->getAllCount(),
            'source'=>2,
            'type'=>3,
            'create_time'=>date('Y-m-d H:i:s'),
            'update_time'=>date('Y-m-d H:i:s'),
        ];
        // 异步写入藏品铸造数量消耗日志
        dispatch(new MerchansCastingJob($log,$special_id));

        return [
            'code' => $insert_data['code'],
        ];
    }
}
